# Author: Chris Moyer
import re
import sys
import os, os.path
import mimetypes
from marajo.appengine.handlers import RequestHandler
from marajo.appengine.ext.webapp import status

import logging
log = logging.getLogger("marajo.handlers.static")

class StaticHandler(RequestHandler):
	"""
	Handle serving up static files
	"""

	def get(self):
		self.response.cache_expires(36000) # Set cache to 10 minutes
		if self.config.has_key("static_dir"):
			match = re.match("^%s(([0-9a-zA-Z\-\/\\_]|\.[0-9a-zA-Z\-\/\\_])*)(\?.*)?$" % self.config['url'], self.request.url[len(self.request.host_url):])
			log.debug("^%s(.*)$" % self.config['url'])
			log.debug("Got: %s" % self.request.url[len(self.request.host_url):])
			if match is not None:
				file_name = match.group(1)
				log.debug("Matched: %s" % file_name)
				# Only specific characters and disallow ".."
				if not re.match("^([0-9a-zA-Z\-\/\\_]|\.[0-9a-zA-Z\-\/\\_])*$", file_name):
					self.error(status.HTTP_BAD_REQUEST)
					return
				file_path = "%s%s" % (self.config['static_dir'], file_name)
				m = re.match("^(.*)(\.[^\.]*)$" ,file_name)
				if m is not None:
					mtype = mimetypes.types_map.get(m.group(2), "application/octet-stream")
					self.response.content_type = mtype
				log.debug("Find: %s" % file_path)
				if os.path.exists(file_path):
					try:
						file_hand = open(file_path, "rb")
						self.response.write(file_hand.read())
					except:
						self.error(status.HTTP_FORBIDDEN)
				else:
					self.error(status.HTTP_NOT_FOUND)
			else:
				self.error(status.HTTP_NOT_FOUND)
		elif self.config.has_key("static_file"):
			log.debug("Static file: %s" % self.config.get("static_file"))
			m = re.match("^(.*)(\.[^\.]*)$", self.config.get("static_file"))
			if m is not None:
				mtype = mimetypes.types_map.get(m.group(2), "application/octet-stream")
				self.response.content_type = mtype
			if os.path.exists(self.config.get("static_file")):
				try:
					file_hand = open(self.config.get("static_file", "rb"))
					self.response.write(file_hand.read())
				except:
					self.error(status.HTTP_FORBIDDEN)
			else:
				self.error(status.HTTP_NOT_FOUND)
